package org.kwisatz.proxybot.core;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.kwisatz.proxybot.Filter;
import org.kwisatz.proxybot.FilterAdapter;
import org.kwisatz.proxybot.Context;
import org.kwisatz.proxybot.Message;

public class RootFilter extends FilterAdapter
{
	private final static Logger LOGGER =
		Logger.getLogger(RootFilter.class.getName());
	private final Map<String, Filter> filters = new HashMap<String, Filter>();
	
	@Override
	public String handleClientLine(String line, Message message)
	{
		Filter[] bs=getBots();
		for (Filter b : bs)
		{
			try
			{
				if (line == null)
					continue;

				line = b.handleClientLine(line, message);
			}
			catch (Exception ex)
			{
				ex.printStackTrace();
			}
		}
		return line;
	}

	@Override
	public void setContext(Context context)
	{	
		super.setContext(context);
		initDefaultBots();
	}
	
	/** Get the list of bots in a synchronized way */
	private Filter[] getBots()
	{
		synchronized (filters)
		{
			return filters.values().toArray(new Filter[filters.size()]);
		}
	}

	public void add(String className)
		throws InstantiationException, IllegalAccessException, ClassNotFoundException
	{		
		add(Class.forName(className));
	}
	
	public void add(Class filterClass)
		throws InstantiationException, IllegalAccessException
	{
		Filter filter = (Filter) filterClass.newInstance();
		String id = filter.getID();
		if(filters.get(id)!=null)
			throw new IllegalArgumentException("Filter id "+id+" already used.");
		synchronized (filters)
		{
			filter.setContext(context);
			filters.put(id, filter);
		}
	}

	public void remove(String id)
	{
		synchronized (filters)
		{
			filters.remove(id);
		}
	}

	@Override
	public String handleServerLine(String line, Message message)
	{	
		Filter[] bs = getBots();
		for (Filter b : bs)
		{
			try {
				line = b.handleServerLine(line, message);
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
		return line;
	}
	
	private void initDefaultBots()
	{
		NickManager nm = new NickManager();
		nm.setContext(context);
		filters.put(nm.getID(), nm);

		ChanManager cm = new ChanManager();
		cm.setContext(context);
		filters.put(cm.getID(), cm);

		String s = System.getProperty("proxybot.filters");
		if(s != null)
			for (String className : s.split("[\\s+]"))
				try {
					add(className);
				} catch (InstantiationException ex) {
					LOGGER.log(Level.SEVERE, null, ex);
				} catch (IllegalAccessException ex) {
					LOGGER.log(Level.SEVERE, null, ex);
				} catch (ClassNotFoundException ex) {
					LOGGER.log(Level.SEVERE, null, ex);
				}
	}

	public Map<String, Filter> getFilters()
	{
		return Collections.unmodifiableMap(filters);
	}
}
